//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.IO;
using System.Security;
using System.Web;

namespace CommunityServer.Components
{
	/// <summary>
	/// Provides easy (although a bit hacky) access to creating and managing CS directories.
	/// 
	/// Directories are generally important to UrlReWriting
	/// </summary>
	public class WebDirectory
	{
		private WebDirectory()
		{
		}

        /// <summary>
        /// Attempts to created a directory at the specified path with the an empty default.aspx file
        /// </summary>
        public static DirectoryAccess Create(string path)
        {
            return Execute(path, "default.aspx", false);
        }

        /// <summary>
        /// Attempts to create a random text file at the specified directory. Once created, the document
        /// will then be deleted.
        /// </summary>
        public static DirectoryAccess ValidateAccess(string path)
        {
            return Execute(path, string.Format("{0}.txt",Guid.NewGuid()), true);
        }

        /// <summary>
        /// Moves one directory and it's contents to another. If the Old directory does not exist,
        /// Create is called on the new directory.
        /// </summary>
        public static DirectoryAccess Move(string oldPath, string newPath)
        {
            try
            {
                oldPath = FormatPath(oldPath);
                newPath = FormatPath(newPath);

                if(Directory.Exists(oldPath))
                {
					// If the new path already exists, just delete the old one
					if(Directory.Exists(newPath))
						Directory.Delete(oldPath, true);
					else
						Directory.Move(oldPath,newPath);

                    return DirectoryAccess.Success;
                }
                else
                {
					if(!Directory.Exists(newPath))
						return Create(newPath);

					return DirectoryAccess.Success;
                }
            }
            catch(SecurityException)
            {
                return DirectoryAccess.SecurityException;
            }
            catch(UnauthorizedAccessException)
            {
                return DirectoryAccess.UnauthorizedAccessException;
            }

        }

		public static DirectoryAccess Delete(string path)
		{
			try
			{
				path = FormatPath(path);

				if(Directory.Exists(path))
					Directory.Delete(path, true);
				return DirectoryAccess.Success;
			}
			catch(SecurityException)
			{
				return DirectoryAccess.SecurityException;
			}
			catch(UnauthorizedAccessException)
			{
				return DirectoryAccess.UnauthorizedAccessException;
			}
		}

        /// <summary>
        /// Internal method used to convert a web based path to a lcoal path
        /// </summary>
        private static string FormatPath(string path)
        {
            if(path.StartsWith("~/") || path.StartsWith("/"))
                path = HttpContext.Current.Server.MapPath(path);

            return path;
        }

        /// <summary>
        /// Creates a new directory and file at the specified values. Optioanlly, the new file can be deleted.
        /// </summary>
        private static DirectoryAccess Execute(string path, string fileName, bool delete)
        {
            try
            {
                path = FormatPath(path);

                if(!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                string fullPath = Path.Combine(path,fileName);

                StreamWriter sw = new StreamWriter(fullPath);
                sw.Close();
                

                if(delete)
                    File.Delete(fullPath);

                return DirectoryAccess.Success;
            }
            catch(SecurityException)
            {
                return DirectoryAccess.SecurityException;
            }
            catch(UnauthorizedAccessException)
            {
                return DirectoryAccess.UnauthorizedAccessException;
            }
        }

       
	}
}
